//////////////////////////////////////////////////////
// 程序名称：设计具有宽度的画线算法，并处理线条连接处出现缺口的问题
// 功 能：画一些具有宽度的线;不能区分线宽为奇数与相邻的偶数的情况
// 编译环境：Visual Studio 2017，EasyX_20190219(beta)
// 作 者：xyqlx<mxxyqlx@qq.com>
// 最后修改：2019-3-7
#include <conio.h>
#include <graphics.h>
#include <cmath>

void Boldline(int x1, int y1, int x2, int y2, int width, COLORREF color);

int main()
{
	// 创建绘图窗口，大小为 640x480 像素
	initgraph(640, 480);
	//填充背景为白色
	setbkcolor(WHITE);
	cleardevice();
	//开始绘制
	setlinecolor(RED);
	
	//画从中心向四周辐射的多条线段
	const int n = 36;
	float PI = float(acos(0) * 2);
	for (int i = 0; i < n; i++) {
		int rx = 320 + int(100 * cos(i * 2 * PI / n));
		int ry = 240 + int(100 * sin(i * 2 * PI / n));
		int px = 320 + int(200 * cos(i * 2 * PI / n));
		int py = 240 + int(200 * sin(i * 2 * PI / n));
		Boldline(rx, ry, px, py, 1 + i, RED);
	}
	//在中间画测试垂直连接的线段
	Boldline(270, 190, 370, 190, 5, BLUE);
	Boldline(370, 190, 370, 290, 5, BLUE);
	Boldline(370, 290, 270, 290, 5, BLUE);
	Boldline(270, 290, 270, 190, 5, BLUE);

	//结束绘制
	_getch();              // 按任意键继续
	closegraph();          // 关闭绘图窗口
	return 0;
}

void Boldline(int x1,int y1,int x2,int y2,int width,COLORREF color){
	int a,b,d1,d2,d,x,y;
	width >>= 1;
	//画线头
	for (y = -width; y <= width;++y){
		for (x = -width; x <= width; ++x)
		{
			if((x<0?-x:x)+(y<0?-y:y) < width + (width>>2)){
				putpixel(x1 + x, y1 + y, color);
				putpixel(x2 + x, y2 + y, color);
			}
		}
	}
	//使x2>x1
	if (x1 > x2)
	{
		x1 ^= x2;
		x2 ^= x1;
		x1 ^= x2;
		y1 ^= y2;
		y2 ^= y1;
		y1 ^= y2;
	}
	x = x2 - x1;
	y = y2 - y1;
	//使用三角函数进行宽度处理
	if(x1!=x2){
		if(y>-x && y<x)
			width = width * sqrt(1 + y*y / float(x*x));
		else
			width = width * float(x) / abs(y) * sqrt(1 + y*y / float(x*x));
	}
	//分类讨论
	if(y >= x){
		a=x1-x2;b=y2-y1;
		d=2*a+b;
		d1=2*(a+b);
		d2=2*a;
		x=x1;
		y=y1;
		putpixel(x,y,color);
		while(y<y2)
		{
			if(d<0) {x++;y++; d+=d1;}
			else {y++; d+=d2;}
			putpixel(x, y, color);
			for (int i = 1; i <= width;++i)
			{
				putpixel(x+i, y, color);
				putpixel(x-i, y, color);
			}
		}
	}
	else if(y <= x && y >= 0){
		a=y1-y2;b=x2-x1;
		d=2*a+b;
		d1=2*(a+b);
		d2=2*a;
		x=x1;
		y=y1;
		putpixel(x,y,color);
		while(x<x2)
		{
			if(d<0) {x++;y++; d+=d1;}
			else {x++; d+=d2;}
			putpixel(x,y,color);
			for (int i = 1; i <= width;++i)
			{
				putpixel(x, y+i, color);
				putpixel(x, y-i, color);
			}
		}
	}
	else if(y>=-x){
		a=y2-y1;b=x2-x1;
		d=2*a+b;
		d1=2*(a+b);
		d2=2*a;
		x=x1;
		y=y1;
		putpixel(x,y,color);
		while(x<x2)
		{
			if(d<0) {x++;y--; d+=d1;}
			else {x++; d+=d2;}
			putpixel(x,y,color);
			for (int i = 1; i <= width;++i)
			{
				putpixel(x, y+i, color);
				putpixel(x, y-i, color);
			}
		}
	}
	else{
		a=x1-x2;b=y1-y2;
		d=2*a+b;
		d1=2*(a+b);
		d2=2*a;
		x=x1;
		y=y1;
		putpixel(x,y,color);
		while(y>y2)
		{
			if(d<0) {x++;y--; d+=d1;}
			else {y--; d+=d2;}
			putpixel(x,y,color);
			for (int i = 1; i <= width;++i)
			{
				putpixel(x+i, y, color);
				putpixel(x-i, y, color);
			}
		}
	}
}